package com.hs.permission.judge;


import com.hs.permission.service.SecurityUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.Collection;

/**
 * 自定义权限注解验证
 * 过滤器对token进行校验只有token正确才能通过过滤器
 * 到此处为止用户虽然可以认证了，但是程序仍然不知道权限的验证逻辑，所以我们需要编写权限的验证逻辑类。
 * 这里需要自定义对hasPermission()方法的处理，
 * 就需要自定义PermissionEvaluator，创建类CustomPermissionEvaluator，实现PermissionEvaluator接口。
 */
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
 
 
    @Autowired
    private SecurityUserService securityUserService;

    /**
     * hasPermission鉴权方法
     * 这里仅仅判断PreAuthorize注解中的权限表达式
     * 实际中可以根据业务需求设计数据库通过targetUrl和permission做更复杂鉴权
     * 当然targetUrl不一定是URL可以是数据Id还可以是管理员标识等,这里根据需求自行设计
     * @Param  authentication  用户身份(在使用hasPermission表达式时Authentication参数默认会自动带上)
     * @Param  targetDomainObject 访问资源需要的权限，如：用户管理。  也可以是请求路径
     * @Param  permission 权限编码，如：sys:user:list
     * @Return boolean 是否通过
     */
    @Override
    public boolean hasPermission(
            Authentication authentication, Object targetDomainObject, Object permission) {
 
        System.out.println("=======" + permission);
        // 获得loadUserByUsername()方法的结果
        //TSystemUser user = (TSystemUser) authentication.getPrincipal();
 
        // 获得loadUserByUsername()中注入的权限
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
 
        // 遍历用户权限进行判定
        for (GrantedAuthority authority : authorities) {
 
            // 如果访问的Url和权限用户符合的话，返回true
            String p = authority.getAuthority();

            if (permission.equals(p)) {
                return true;
            }
        }
 
        return false;
    }
 
    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}